package com.sudo.api.config;

import com.sudo.common.exception.BizException;
import com.sudo.common.utils.JsonRes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.mail.MailSendException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.sql.SQLException;
import java.util.Objects;

@Slf4j
@Order(9999)
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = Throwable.class)
    public JsonRes handlerThrowable(Throwable e) {
        log.error("请求异常：",e);
        String message = ExceptionUtils.getRootCauseMessage(e);
        JsonRes jsonRes= JsonRes.errorMsg("服务异常,请联系管理员："+message);
        MDC.clear();
        return jsonRes;
    }


    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = BizException.class)
    public JsonRes handlerBizException(BizException e) {
        log.error("业务异常：",e);
        JsonRes jsonRes = JsonRes.errorMsg(e.getMessage());
        MDC.clear();
        return jsonRes;
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public JsonRes handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("参数校验失败：",e);
        BindingResult bindingResult = e.getBindingResult();
        String defaultMessage = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
        JsonRes jsonRes = JsonRes.errorMsg(defaultMessage);
        MDC.clear();
        return jsonRes;
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = NullPointerException.class)
    public JsonRes handlerNullPointerException(NullPointerException e) {
        log.error("空指针异常：",e);
        JsonRes jsonRes = JsonRes.errorMsg(e.getMessage());
        MDC.clear();
        return jsonRes;
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = IllegalArgumentException.class)
    public JsonRes handlerIllegalArgumentException(IllegalArgumentException e) {
        log.error("参数不合法：",e);
        JsonRes jsonRes = JsonRes.errorMsg(e.getMessage());
        MDC.clear();
        return jsonRes;
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = SQLException.class)
    public JsonRes handlerSQLException(SQLException e) {
        log.error("SQL异常：",e);
        JsonRes jsonRes = JsonRes.errorMsg(e.getMessage());
        MDC.clear();
        return jsonRes;
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = MailSendException.class)
    public JsonRes handlerMailSendException(Throwable e) {
        log.error("邮件发送异常：",e);
        MailSendException exception = (MailSendException) e;
        String message;
        if (exception.getRootCause() != null) {
            message = exception.getRootCause().getMessage();
        }else {
            message = exception.getMessage();
        }
        JsonRes jsonRes = JsonRes.errorMsg(message);
        MDC.clear();
        return jsonRes;
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    public JsonRes handlerMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
        log.error("参数类型不匹配：",e);
        String message;
        if (e.getRootCause() != null) {
            message = e.getRootCause().getMessage();
        }else {
            message = e.getMessage();
        }
        JsonRes jsonRes = JsonRes.errorMsg(message);
        MDC.clear();
        return jsonRes;
    }
    
}
